Skip to content

Player Devtools MCP#12

Merged
sugarmanz merged 5 commits into
mainfrom
mcp
Jun 29, 2026
Merged

Player Devtools MCP#12
sugarmanz merged 5 commits into
mainfrom
mcp

Conversation

@sugarmanz

@sugarmanz sugarmanz commented Apr 8, 2026

Copy link
Copy Markdown
Member

What's changing

This PR adds an MCP server for agent-driven Player debugging, fixes a set of devtools messenger routing bugs that surface on that path, and documents the devtools workspace.

1. @player-devtools/mcp — agent access to devtools

A new MCP server that exposes the Player UI Devtools to AI agents (e.g. Claude) over stdio. It connects to live Players through a flipper-server and re-exposes them as MCP tools: list_players, get_player_status, get_flow, get_data, get_logs, get_plugin_data, describe_plugin, select_player, and invoke_action.

  • Decoupled transport via a Transport interface; the shipped FlipperServerTransport refcounts a shared flipper-server daemon across processes (first in starts it, last out tears it down) so multiple agent registrations don't each spawn or prematurely kill the server.
  • The server is plugin-agnostic — it discovers whatever devtools plugins are connected at runtime; no per-plugin wiring.
  • Ships a player-devtools-mcp CLI; registers with claude mcp add player-devtools -- npx -y @player-devtools/mcp@latest.

2. Messenger routing fixes

Three sequencing bugs in @player-devtools/messenger / the core plugin that caused targeted messages to be dropped — exactly the traffic pattern the MCP server's selectinvoke_action flow produces. Each is covered by a regression test and was verified by reverting the fix in isolation:

  • Broadcasts (id === -1) no longer advance the receiver's messagesReceived, which had made the next targeted message look like a duplicate and be dropped.
  • sendMessage no longer double-increments messagesSent (it was already stamped by getTransactionID), which had desynced ids and triggered spurious lost-event recovery.
  • The plugin interaction cursor now advances before processing, so a synchronous re-entrant dispatch (SELECTED_PLAYER_CHANGE) doesn't reprocess the same interaction.

invoke_action also now addresses the resolved playerId via target, so an explicit player isn't misrouted to the currently-selected one.

3. Documentation pass

READMEs across the devtools workspace, consolidated one-per-family (each covers all its platform packages — TS, JVM, Android, iOS, SwiftUI):

  • New: mcp, plugins/basic, plugins/profiler, types, utils.
  • Rewritten: plugin and messenger families (messenger also fixes stale API docs — removed a nonexistent target ctor option, added the required logger, fixed the import path).
  • Promoted the devtools overview to the repo-root README; tidied client.
  • Each README leads with installation (npm / Maven / SPM, plus claude mcp add).

4. Profiler plugin consistency (alongside the new profiler plugin)

  • Aligned the profiler's Maven group / Kotlin package convention with basic (com.intuit.playerui.devtools.plugins.*).
  • Added a capabilities descriptor to ProfilerPluginData so the profiler is discoverable via the MCP describe_plugin tool.

Tests

  • New regression suites: messenger target routing, plugin interaction re-entrancy, and invoke_action routing (unit + integration).
  • Each messenger/plugin fix was validated by reverting it in isolation and confirming the corresponding test fails.
  • Profiler JVM builds, tests, and ktlints pass after the package rename; Android builds.

Documentation

  • Full README coverage for every devtools package family (see section 3).

Change Type (required)

  • patch
  • minor
  • major

Release Notes

Added @player-devtools/mcp, an MCP server that exposes the Player UI Devtools to AI agents. Point an MCP client at it over stdio:

claude mcp add player-devtools -- npx -y @player-devtools/mcp@latest

It connects to live Players through a shared flipper-server and exposes tools to list players, read flow/data/logs/plugin state, and invoke plugin actions. Also includes messenger routing fixes for reliable targeted message delivery and README documentation across the devtools workspace.

@sugarmanz sugarmanz added the minor Increment the minor version when merged label Apr 8, 2026
sugarmanz and others added 5 commits June 29, 2026 06:25
Introduces `@player-devtools/mcp` — a Model Context Protocol server that
exposes Player runtime state (players, flows, data, logs, plugin data) as
MCP tools queryable by AI agents (e.g. Claude).

- Extract `useStateReducer` from `plugin/core` → `@player-devtools/utils`
- Extract `createExtensionClient` pure factory from `useExtensionState`
- Add `FlipperServerTransport` with auto-start headless `flipper-server`
- Register 9 MCP tools: list_players, get_player_status, get_flow, get_data,
  get_logs, get_plugin_data, describe_plugin, select_player, invoke_action

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Messenger sequencing fixes (verified by isolated revert + regression tests):
- Broadcasts (id === -1) no longer advance the receiver's messagesReceived;
  otherwise a following targeted message looked like a duplicate and was dropped.
- Stop double-incrementing messagesSent in sendMessage — getTransactionID
  already stamps and increments it, so the second bump desynced ids and
  triggered spurious lost-event recovery.
- Advance the plugin interaction cursor before processing so a synchronous
  re-entrant dispatch (SELECTED_PLAYER_CHANGE) doesn't reprocess the same
  interaction.

MCP server:
- invoke_action now addresses the resolved playerId via target so an explicit
  player isn't misrouted to the currently selected one; handleInteraction takes
  an optional target.
- Migrate tools to a declarative ToolDef table registered via McpServer; share
  Zod input shapes across the player-scoped tools.
- Refcount the shared flipper-server daemon across MCP processes; drop the
  unused WebSocketServerTransport.

Add regression tests for messenger target routing, plugin re-entrancy, and
invoke_action routing.
Add or rewrite READMEs across the devtools workspace, source-grounded and
consolidated one-per-family (each covers all its platform packages — TS, JVM,
Android, iOS, SwiftUI):

- New: mcp, flipper-plugin, plugins/basic, types, utils
- Rewritten: plugin and messenger families (messenger also fixes a stale API
  doc — removed a nonexistent `target` ctor option, added the required `logger`,
  fixed the import path)
- Promote the devtools overview to the repo-root README (workspace map +
  architecture) and drop the nested devtools/README stub
- client: drop the broken license badge and dangling external reference, add
  sibling cross-links

Each README leads with installation (npm / Maven / SPM, plus `claude mcp add`
for the MCP server) and links to siblings; all cross-links and anchors resolve.
- Add a consolidated README for the profiler plugin family (core, content,
  react, jvm, android, ios, swiftui), following the basic-plugin template, and
  list it in the root README.
- Make the Maven group / Kotlin package convention consistent with basic:
  move the profiler Kotlin packages from com.intuit.playerui.plugins.devtools.profiler
  to com.intuit.playerui.devtools.plugins.profiler, and derive the Maven group
  from GROUP via "%s.plugins" % GROUP in both BUILD files. Update the Android
  manifest package and add an explicit R import so the rename compiles.
- Declare a capabilities block on ProfilerPluginData (data keys + start/stop/
  reset-profiling actions) so the profiler is discoverable via the MCP
  describe_plugin tool.
@sugarmanz sugarmanz marked this pull request as ready for review June 29, 2026 14:07
@sugarmanz sugarmanz requested a review from a team as a code owner June 29, 2026 14:07
@sugarmanz sugarmanz merged commit a02b769 into main Jun 29, 2026
8 checks passed
@sugarmanz sugarmanz deleted the mcp branch June 29, 2026 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

minor Increment the minor version when merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant